<template>
  <el-card class="batch-detection-container">
    <el-page-header @back="$router.push('/user-center/domain-detection')" content="批量域名检测"></el-page-header>
    <el-alert title="为确保能够正常访问，检查入口域名和落地域名是否被微信、QQ、钉钉等平台拦截！" type="warning" show-icon>
    </el-alert>
    <el-form ref="batchDetectFormRef" :model="batchData.batchForm" label-position="top">
      <el-row :gutter="40">
        <el-col :span="14">
          <el-form-item label="批量检测">
            <el-input type="textarea" :rows="9" :autosize="{ minRows: 9, maxRows: 9 }" resize="none" v-model="batchData.batchForm.urlArr" placeholder="请选择域名、链接或IP接口，一行一个，回车换行。" :disabled="batchData.detecting">
            </el-input>
            <div class="to-be-tested">
              待检测：
              <span class="to-be-tested-num">
                {{ batchData.batchForm.urlArr.trim() ? [...new Set(batchData.batchForm.urlArr.split('\n').filter(item=>item.trim() !== ''))].length : 0 }}
              </span>
              <span class="to-be-tested-text"> 条域名</span>
            </div>
          </el-form-item>
        </el-col>
        <el-col :span="10" class="select-function-col">
          <el-form-item label="选择检测功能">
            <el-tag type="primary" :closable="!batchData.detecting" v-for="item in batchData.selectJcArr" :key="item.interface_name" @close="removeJc(item)">
              {{ item.name }}
            </el-tag>
            <el-select v-model="batchData.batchForm.apiArr" placeholder="最多选择6个" @change="switchApi" value-key="interface_name" :disabled="batchData.detecting || batchData.apiDropDisable">
              <el-option v-for="item in batchData.apiList" :key="item.id" :label="item.name" :value="{ name: item.name, interface_name: item.interface_name }" :disabled="item.disabled">
              </el-option>
            </el-select>
          </el-form-item>
          <el-button type="primary" :loading="batchData.detecting" element-loading-text="检测中" @click="detectNow">立即检测</el-button>
        </el-col>
        <el-col :span="24">
          <h3>检测结果</h3>
          <div class="batch-result-header">
            <h4>
              检测域名：<span class="primary-text">{{ batchData.detectTotal }}</span>个，
              需请求接口：<span class="primary-text">{{ batchData.detectTotal * batchData.selectJcArr.length }}</span>个，
              检测成功：<span class="success-text">{{ batchData.successNums }}</span>个，
              检测失败：<span class="danger-text">{{ batchData.failedNums }}</span>个，
              待检测：<span class="secondary-text">{{ batchData.toBeTested }}</span>个。
            </h4>
            <el-button-group>
              <el-button type="danger" size="mini" @click="failedRecheck" :disabled="batchData.detecting || batchData.failedNums <= 0" icon="el-icon-refresh">失败重查</el-button>
              <el-button type="success" size="mini" @click="detectNew" :disabled="batchData.detecting || batchData.toBeTested <= 0" icon="el-icon-folder-add">检测新增</el-button>
              <el-button type="warning" size="mini" icon="el-icon-upload2" @click="exportResult" :disabled="batchData.detecting || batchData.tableResult <= 0">导出结果</el-button>
            </el-button-group>
          </div>
        </el-col>
        <el-col :span="24">
          <el-table class="batch-result-table" :data="batchData.tableResult" v-if="batchData.showResult">
            <el-table-column prop="time" label="检测时间" width="180px">
            </el-table-column>
            <el-table-column prop="domain" label="域名" show-overflow-tooltip>
            </el-table-column>
            <el-table-column v-for="item in batchData.selectJcArr" :key="item" :prop="item.interface_name" :label="item.name" show-tooltip-when-overflow>
              <template #default="scope">
                <i v-if="scope.row[item.interface_name] === 'loading'" class="el-icon-loading"></i>
                <span :style="`color:${[200,0].includes(scope.row[item.interface_name]?.code) ? 'green' : 'red'}`" v-else-if="scope.row[item.interface_name]?.code">
                  {{ scope.row[item.interface_name]?.msg }}
                </span>
                <span class="secondary-text" v-else>{{ scope.row[item.interface_name]?.msg }}</span>
              </template>
            </el-table-column>
          </el-table>
          <div class="empty-box" v-else>
            <img class="empty-img" src="/img/404-images/empty.png" alt="暂无内容" height="215">
            <span class="empty-text">暂无数据</span>
          </div>
        </el-col>
      </el-row>
    </el-form>
  </el-card>
</template>

<script setup>
import { reactive, getCurrentInstance } from 'vue'
import { apilist, getMonitorRel } from '@/axios/userRequest'
import { exportExcel } from '@/utils/utils'
import store from '@/store/Store'
import { onBeforeRouteLeave } from 'vue-router'
const { proxy } = getCurrentInstance()

const batchData = reactive({// 批量检测数据
  formData: { // 请求接口表单
    data: {
      url: '',
      token: store.state.userStore.token
    },
    api: '',
    interface_name: ''
  },
  batchForm: {// 表单绑定数据
    urlArr: '',
    apiArr: ''
  },
  apiDropDisable: false,// api下拉菜单禁用
  tableResult: [],// 检测结果
  showResult: false,// 显示结果
  apiList: [],// 检测api列表
  detecting: false,// 检测中
  selectJcArr: [],// 已选择的检测功能
  successNums: 0,// 成功接口个数
  failedNums: 0,// 失败接口个数
  testNums: 0,// 已经请求的接口数
  detectTotal: 0,// 检测的域名总数量
  toBeTested: 0,// 待检测个数
})

// 页面离开前
onBeforeRouteLeave((to, from, next)=>{
  if(!batchData.detecting) return next()
  proxy.$confirm('正在进行域名批量检测，离开后检测结果将丢失，您可以直接离开或等待检测完成并导出结果后再离开。','提示',{
    closeOnClickModal: false,
    customClass: 'commonMessageBox',
    cancelButtonText: '再等等',
    confirmButtonText: '确认离开',
    type: 'warning',
  }).then(()=> next())
    .catch(err=> next(false))
})

// 获取检测api
const getApiList = async ()=>{
  const res = await apilist()
  res.code === 0 ? batchData.apiList = res.data : proxy.$message.error(res.msg)
}
getApiList()
// 选择检测功能
const switchApi = val=>{
  batchData.batchForm.apiArr = ''
  if(!JSON.stringify(batchData.selectJcArr).includes(JSON.stringify(val)) && batchData.selectJcArr.length < 6){
    batchData.selectJcArr.push(val)
    batchData.selectJcArr.length >= 6 ? batchData.apiDropDisable = true : ''
    batchData.apiList.forEach(api => api.interface_name === val.interface_name ? api.disabled = true : '')
    if(batchData.tableResult.length > 0){
      batchData.tableResult.forEach(item => {
        item[val.interface_name] = { msg: '未检测' }
        batchData.toBeTested++
      })
    }
  }
}
// 移除选择的检测
const removeJc = api=>{
  let index = batchData.selectJcArr.indexOf(api)
  if(index !== -1){
    batchData.apiDropDisable = false
    batchData.selectJcArr.splice(index, 1)
    batchData.apiList.forEach(item => item.interface_name === api.interface_name ? item.disabled = false : '')
    batchData.tableResult.forEach(item=>{
      batchData.testNums--
      if(item[api.interface_name]?.code === 500){
        batchData.failedNums--
      }else if([200,0,201].includes(item[api.interface_name]?.code)){
        batchData.successNums--
      }else{
        batchData.toBeTested--
      }
    })
  }
}
// 立即检测
const detectNow = ()=>{
  if(batchData.batchForm.urlArr.trim() === '') return proxy.$message.error('请输入要检测的域名。')
  if(batchData.selectJcArr.length === 0) return proxy.$message.error('请选择检测功能。')
  batchData.tableResult = []
  batchData.detecting = batchData.showResult = true
  batchData.testNums = batchData.successNums = batchData.failedNums = 0
  let domainArr = [...new Set(batchData.batchForm.urlArr.split('\n').filter(item=>item.trim() !== ''))]
  batchData.detectTotal = domainArr?.length
  batchData.toBeTested = batchData.detectTotal * batchData.selectJcArr.length
  domainArr.forEach((item,index)=>{
    batchData.formData.data.url = item
    batchData.tableResult.push({ domain: item, time: proxy.$filter('YYYY-mm-dd HH:MM:SS', new Date()) })
    batchData.selectJcArr.forEach(api=> detectMethod(item,api,index,'now'))
  })
}
// 失败重查
const failedRecheck = ()=>{
  if(batchData.failedNums <= 0) return proxy.$message.error('没有失败的检测。')
  batchData.detecting = true
  batchData.toBeTested = batchData.failedNums
  batchData.testNums = batchData.failedNums = 0
  batchData.tableResult.forEach((item,index)=>{
    batchData.formData.data.url = item.domain
    item.time = proxy.$filter('YYYY-mm-dd HH:MM:SS', new Date())
    batchData.selectJcArr.forEach(async api=>{
      [-1,-2,500].includes(item[api.interface_name].code) ? await detectMethod(item,api,index,'failed') : batchData.testNums++
    })
  })
}
// 检测新增
const detectNew = ()=>{
  if(batchData.toBeTested <= 0) return proxy.$message.error('没有新增的检测。')
  batchData.detecting = true
  batchData.testNums = 0
  batchData.tableResult.forEach((item,index)=>{
    batchData.formData.data.url = item.domain
    item.time = proxy.$filter('YYYY-mm-dd HH:MM:SS', new Date())
    batchData.selectJcArr.forEach(async api=>{
      item[api.interface_name].msg === '未检测' ? await detectMethod(item,api,index,'new') : batchData.testNums++
    })
  })
}
// 检测方法封装
const detectMethod = (item,api,index,type)=>{
  type === 'now' ? batchData.tableResult[index][api.interface_name] = 'loading' : item[api.interface_name] = 'loading'
  setTimeout(async ()=>{
    batchData.formData.api = `${ store.state.userStore.jcApiUrl }/${api.interface_name}`
    batchData.formData.interface_name = api.interface_name
    const res = await getMonitorRel(batchData.formData)
    if(res.code === 0 && res.data[api.interface_name] && res.data[api.interface_name]?.code !== 500){
      type === 'now' ? batchData.tableResult[index][api.interface_name] = res.data[api.interface_name] : item[api.interface_name] = res.data[api.interface_name]
      res.data[api.interface_name]?.code === -1 || res.data[api.interface_name]?.code === -2 ? batchData.failedNums++ : batchData.successNums++
      batchData.testNums++
      batchData.toBeTested--
    }else{
      let errData = { code: 500, msg: '检测失败' }
      type === 'now' ? batchData.tableResult[index][api.interface_name] = errData : item[api.interface_name] = errData
      batchData.failedNums++
      batchData.testNums++
      batchData.toBeTested--
    }
    batchData.testNums === batchData.detectTotal * batchData.selectJcArr.length ? batchData.detecting = false : ''
  },index*300)
}
// 导出结果
const exportResult = ()=> exportExcel('.batch-result-table',`${ proxy.$filter('YYYY-mm-dd HH点MM分SS', new Date()) } 批量检测结果`)
</script>

<style lang="less" scoped>
.batch-detection-container{
  border-radius: 52px 12px 12px;
  min-height: 100%;
  &:deep(.el-card__body) {
    box-sizing: border-box;
    padding: 40px 30px 20px;
    .el-page-header{
      .el-page-header__left{
        color: @primary;
      }
      .el-page-header__content{
        font-weight: bold;
        font-size: 20px;
      }
    }
    .el-alert{
      margin: 20px 0;
      color: @success;
      border-color: @success;
      background-color: @success-plain;
      .el-alert__icon{
        color:@success;
      }
    }
    .el-form{
      .el-form-item{
        margin-bottom: 0;
        .el-form-item__label{
          font-size: 16px;
          color: @title;
        }
        .el-form-item__content{
          .to-be-tested{
            text-align: right;
            font-size: 14px;
            .to-be-tested-num{
              color: @primary;
            }
            .to-be-tested-text{
              color: @secondary;
            }
          }
          .el-textarea{
            .el-textarea__inner{
              white-space: nowrap;
              overflow: auto;
            }
          }
        }
      }
    }
    .el-row{
      .el-col{
        .batch-result-header{
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin: 15px 0;
          h4{
            margin: 0;
          }
        }
        .empty-box{
          display: flex;
          align-items: center;
          justify-content: center;
          flex-direction: column;
          margin-top: 20px;
          .empty-text{
            color: @tips-text;
            margin-top: 25px;
            font-size: 16px;
          }
        }
      }
      .select-function-col{
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        .el-tag{
          border: none;
          border-radius: 16px;
          max-height: 30px;
          padding: 0 12px;
          margin-right: 20px;
        }
        .el-select{
          width: 100%;
          margin-top: 12px;
        }
        .el-button{
          width: 140px;
          height: 40px;
          border-radius: 2px;
          margin-bottom: 40px;
        }
      }
    }
  }
}
</style>

<style lang="less">
.el-select-dropdown__item{
  background-color: #FFFFFF!important;
  &:hover{
    background-color: #f5f7fa!important;
  }
}
</style>
